#ifndef CHANNEL_H
#define CHANNEL_H

#include <functional>

class EventLoop;

class Channel {
public:
    enum ChannelState {
        NEW,
        ADDED,
        DELETED
    };

    typedef std::function<void()> EventCallback;

    Channel(EventLoop* loop, int fd);
    ~Channel() = default;

    void handleEvent();

    void setReadCallback(EventCallback cb) {
        readCallback_ = std::move(cb);
    }
    void setWriteCallback(EventCallback cb) {
        writeCallback_ = std::move(cb);
    }
    void setCloseCallback(EventCallback cb) {
        closeCallback_ = std::move(cb);
    }
    void setErrorCallback(EventCallback cb) {
        errorCallback_ = std::move(cb);
    }

    int getFd() const { return fd_; }
    int getEvents() const { return events_; }
    void setREvent(int revt) { revents_ = revt; }
    bool isNoneEvent() { return events_ == kNoneEvent; }

    void enableReading() { events_ |= kReadEvent; update(); } 
    void disableReading() { events_ &= (~kReadEvent); update(); }
    void enableWriting() { events_ |= kWriteEvent; update(); } 
    void disableWriting() { events_ &= (~kWriteEvent); update(); }
    void disableAll() { events_ = kNoneEvent; update();}
    bool isReading() { return events_ & kReadEvent; }
    bool isWriting() { return events_ & kWriteEvent; }

    int getState() { return state_; }
    void setState(int state) { state_ = state; }

private:
    void update();

    static const int kNoneEvent;
    static const int kReadEvent;
    static const int kWriteEvent;

    EventLoop* loop_;
    const int fd_;
    int events_;
    int revents_;
    int state_;

    EventCallback readCallback_;
    EventCallback writeCallback_;
    EventCallback closeCallback_;
    EventCallback errorCallback_;
};

#endif